import { useEffect, useRef, useState, useCallback } from 'react';
import { io, Socket } from 'socket.io-client';
import { ChatMessage, ChatUser, generateRandomUsername } from '../types/chat';
import { apiClient } from '../lib/api';

interface UseTokenChatOptions {
  autoConnect?: boolean;
  username?: string;
}

interface TokenChatState {
  connected: boolean;
  connecting: boolean;
  error: string | null;
  messages: ChatMessage[];
  users: ChatUser[];
  currentUser: string | null;
  socket: Socket | null;
  tokenMint: string | null;
}

export function useTokenChat(tokenMint?: string, options: UseTokenChatOptions = {}) {
  const { autoConnect = true, username } = options;
  
  const [state, setState] = useState<TokenChatState>({
    connected: false,
    connecting: false,
    error: null,
    messages: [],
    users: [],
    currentUser: null,
    socket: null,
    tokenMint: tokenMint || null,
  });

  const socketRef = useRef<Socket | null>(null);
  const usernameRef = useRef<string>(username || generateRandomUsername());
  const currentTokenRef = useRef<string | null>(tokenMint || null);

  const connect = useCallback(() => {
    if (socketRef.current?.connected || !tokenMint) {
      return;
    }

    setState(prev => ({ ...prev, connecting: true, error: null }));

    // 获取基础WebSocket URL
    const wsUrl = apiClient.getWebSocketBaseUrl();
    const fullUrl = `${wsUrl}/token-chat`;

    console.log('Token WebSocket connection details:', {
      baseUrl: wsUrl,
      fullUrl: fullUrl,
      tokenMint: tokenMint,
      username: usernameRef.current,
    });

    // 先测试基础连接
    console.log('Testing Socket.IO connection to:', fullUrl);

    try {
      const socket = io(fullUrl, {
        transports: ['websocket', 'polling'],
        timeout: 10000,
        autoConnect: false,
        auth: {
          username: usernameRef.current,
          tokenMint: tokenMint,
        },
        query: {
          tokenMint: tokenMint,
        }
      });

      // 连接事件
      socket.on('connect', () => {
        console.log('Token chat connected successfully for token:', tokenMint);
        setState(prev => ({
          ...prev,
          connected: true,
          connecting: false,
          error: null,
          socket,
          currentUser: usernameRef.current,
          tokenMint: tokenMint,
        }));

        // 加入代币房间
        console.log('Joining token room with data:', { 
          tokenMint: tokenMint,
          username: usernameRef.current 
        });
        socket.emit('joinTokenRoom', { 
          tokenMint: tokenMint,
          username: usernameRef.current 
        });
      });

      socket.on('disconnect', (reason: string) => {
        console.log('Token chat disconnected:', reason);
        setState(prev => ({
          ...prev,
          connected: false,
          connecting: false,
        }));
      });

      socket.on('connect_error', (error: Error) => {
        console.error('Token chat connection error:', error);
        setState(prev => ({
          ...prev,
          connected: false,
          connecting: false,
          error: error.message || '连接失败',
        }));
      });

      // 消息事件
      socket.on('new_message', (message: ChatMessage) => {
        console.log('Token chat message received:', message);
        setState(prev => ({
          ...prev,
          messages: [...prev.messages, message],
        }));
      });

      // 用户事件
      socket.on('user_joined', (data: { user: ChatUser; message?: string }) => {
        console.log('User joined token chat:', data);
        setState(prev => ({
          ...prev,
          users: [...prev.users.filter(u => u.id !== data.user.id), data.user],
          messages: data.message ? [...prev.messages, {
            id: Date.now().toString(),
            message: data.message,
            username: 'System',
            timestamp: new Date().toISOString(),
            isSystem: true,
          }] : prev.messages,
        }));
      });

      socket.on('user_left', (data: { userId: string; message?: string }) => {
        console.log('User left token chat:', data);
        setState(prev => ({
          ...prev,
          users: prev.users.filter(u => u.id !== data.userId),
          messages: data.message ? [...prev.messages, {
            id: Date.now().toString(),
            message: data.message,
            username: 'System',
            timestamp: new Date().toISOString(),
            isSystem: true,
          }] : prev.messages,
        }));
      });

      // 用户名被占用事件
      socket.on('username_taken', (data: { message: string }) => {
        console.log('Username taken in token chat:', data);
        setState(prev => ({
          ...prev,
          error: data.message,
        }));
      });

      socket.on('online_users', (users: ChatUser[]) => {
        console.log('Token chat users list received:', users);
        setState(prev => ({
          ...prev,
          users,
        }));
      });

      socket.on('username_changed', (data: { oldUsername: string; newUsername: string; userId: string }) => {
        console.log('Username changed in token chat:', data);
        setState(prev => ({
          ...prev,
          users: prev.users.map(u => 
            u.id === data.userId ? { ...u, username: data.newUsername } : u
          ),
          currentUser: prev.currentUser === data.oldUsername ? data.newUsername : prev.currentUser,
          messages: [...prev.messages, {
            id: Date.now().toString(),
            message: `${data.oldUsername} 更改用户名为 ${data.newUsername}`,
            username: 'System',
            timestamp: new Date().toISOString(),
            isSystem: true,
          }],
        }));
      });

      // 历史消息
      socket.on('tokenChatHistory', (messages: ChatMessage[]) => {
        console.log('Token chat history received:', messages);
        setState(prev => ({
          ...prev,
          messages: messages,
        }));
      });

      socketRef.current = socket;
      socket.connect();

    } catch (error) {
      console.error('Failed to create token chat socket:', error);
      setState(prev => ({
        ...prev,
        connecting: false,
        error: error instanceof Error ? error.message : '连接失败',
      }));
    }
  }, [tokenMint]);

  const disconnect = useCallback(() => {
    if (socketRef.current) {
      console.log('Disconnecting from token chat...');
      socketRef.current.disconnect();
      socketRef.current = null;
      setState(prev => ({
        ...prev,
        connected: false,
        connecting: false,
        socket: null,
        messages: [],
        users: [],
      }));
    }
  }, []);

  const sendMessage = useCallback((message: string) => {
    if (socketRef.current?.connected && message.trim() && tokenMint) {
      console.log('Sending token chat message:', message);
      socketRef.current.emit('send_message', {
        message: message.trim(),
        tokenMint: tokenMint,
      });
    }
  }, [tokenMint]);

  const changeUsername = useCallback((newUsername: string) => {
    if (socketRef.current?.connected && newUsername.trim()) {
      console.log('Changing username in token chat:', newUsername);
      socketRef.current.emit('change_username', {
        newUsername: newUsername.trim(),
      });
      usernameRef.current = newUsername.trim();
    }
  }, []);

  // 当tokenMint改变时重新连接
  useEffect(() => {
    if (tokenMint !== currentTokenRef.current) {
      currentTokenRef.current = tokenMint || null;
      
      // 断开之前的连接
      if (socketRef.current) {
        disconnect();
      }
      
      // 重置状态
      setState(prev => ({
        ...prev,
        messages: [],
        users: [],
        connected: false,
        connecting: false,
        error: null,
        tokenMint: tokenMint || null,
      }));
      
      // 如果有新的tokenMint且需要自动连接，则连接
      if (tokenMint && autoConnect) {
        setTimeout(() => connect(), 100);
      }
    }
  }, [tokenMint, autoConnect, connect, disconnect]);

  // 初次挂载或初始 tokenMint 就存在时执行自动连接（上面的 effect 仅在 tokenMint 变化时触发，初始不会触发）
  useEffect(() => {
    if (autoConnect && tokenMint && !socketRef.current && !state.connected && !state.connecting) {
      connect();
    }
  }, [autoConnect, tokenMint, state.connected, state.connecting, connect]);

  // 组件卸载时断开连接
  useEffect(() => {
    return () => {
      disconnect();
    };
  }, [disconnect]);

  return {
    connected: state.connected,
    connecting: state.connecting,
    error: state.error,
    messages: state.messages,
    users: state.users,
    currentUser: state.currentUser,
    tokenMint: state.tokenMint,
    sendMessage,
    changeUsername,
    connect,
    disconnect,
  };
}
